home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / serien / purity / nr.5 / pascal / pcq-programme / game / game.doc < prev    next >
Text File  |  1995-04-19  |  22KB  |  511 lines

  1.  
  2.                   Dokumentation Game.i
  3.                   --------------------
  4. 1.  Einleitung
  5.  
  6.     Was macht man (oder Frau), wenn man ein Spiel programmieren will?
  7.     Man macht sich schlau! Und warum? Weil nur wenige Leute Informationen
  8.     über die Spieleprogrammierung veröffentlichen oder man bekommt
  9.     überhaupt keine Infos (so wie ich).
  10.  
  11.     Aber damit ist jetzt Schluß!!!
  12.  
  13.     Warum? Na, ich will euch mit den von mir programmierten Funktionen
  14.     und Ideen dazu bewegen, eigene Spiele zu entwickeln.
  15.  
  16.     Ziel ist es, daß die Routinen so leicht wie möglich aufzurufen
  17.     sind und so effektiv wie möglich arbeiten.
  18.     Ein weiteres Ziel: Jeder soll sie verstehen!!
  19.     Und noch ein weiters Ziel: Es ist egal, ob die Routinen in
  20.     PCQ-Pascal geschrieben sind oder in Assembler (wobei natürlich
  21.     PCQ-Pascal zu bevorzugen ist), hauptsache sie laufen, passen in
  22.     das Gesamtkonzept und sind getestet.
  23.  
  24.     Oh Gott, hoffentlich sind das nicht zu hoch gesteckte Ziele, aber
  25.     wer weiß, wenn ihr voll mit dabei seit, so ist es kein Problem.
  26.  
  27.     Ich (und auch andere) setzen auf euch !!!
  28.  
  29.     Wenn ihr jetzt denkt, daß ein Spiel in Pascal unmöglich zu schreiben
  30.     ist, dann werde ich euch mit meinem ersten Spiel "TakeIt"
  31.     überzeugen. Fertig solls Ende Juli '92 sein.
  32.  
  33.     Soweit zum Vorwort. Und was kommt jetzt?
  34.     Na, die Erläuterung meiner Routinen und Strukturen aus "Game.i"
  35.     natürlich.
  36.     Also fangen wir an.
  37.  
  38.     a) Die zu verwendenden Typen, Constanten und Variablen
  39.  
  40.         - ObjektDef
  41.  
  42.             Dieses ist die eigentliche Struktur für die Definition von
  43.             Spielobjekten. Wenn ihr genauer hinschaut werdet ihr sehen,
  44.             daß sich aus der Graphics.Lib viele Sachen wiederspiegeln
  45.             die dort mit den AnimObjekts verwendet werden.
  46.  
  47.             Ich habe bloß keine Lust, das umständliche Handling der
  48.             Graphics.Lib zu nutzen inkl. der sehr großen Strukturen.
  49.  
  50.             "Na ist den der verrückt geworden?" werdet ihr jetzt denken.
  51.             Nein, ich bin nur jemand, der Wert auf Geschwindigkeit und
  52.             Einfachheit legt und deshalb nicht die AnimObjekt-Routinen
  53.             nutzt. Die laß ich lieber den Basic-Programmieren übrig
  54.             ( hiervon kann jeder reden, der mal die Routinen genutzt hat.
  55.             Einfach Grauenhaft!!!).
  56.  
  57.             Schaut euch die ObjektDef genau an, ihr werdet sie noch oft
  58.             in meinen Routinen sehen.
  59.  
  60.         - Objektsitze
  61.  
  62.             Definiert die Größe eines Objektes in Byte für die Funktion
  63.             CollObjekt (siehe unten).
  64.  
  65.         - Objekt
  66.  
  67.             Ist ein Array von max. 256 Objekten. Dient als eigentliche
  68.             "Spielwiese" für meine Soielobjekte, da hier alle erforder-
  69.             lichen Daten abgelegt sind.
  70.  
  71.         - Picture
  72.  
  73.             Ist wieder ein Kernstück der Routinen. Mit Picture de-
  74.             finiere ich mir ein Array mit 20 Images aus Intuition.
  75.  
  76.             Warum denn das?
  77.             Nun, um Objekt auf den Bildschirm zu bringen kann man Punkte
  78.             verwenden (viel zu aufwendig), Linien (nicht immer zu
  79.             gebrauchen), den Zeichensatz (sehr unflexibel), die Bobs
  80.             (will ich nicht wegen dem Handling) oder die Images.
  81.  
  82.             Was ist der Vorteil der Images?
  83.             Also eins Vorweg: sie werden vom Blitter gezeichnet und sind
  84.             deshalb unheimlich schnell auf dem Bildschirm (siehe auch
  85.             das Testprogramm). Außerdem muß ich nicht in die Blitter-
  86.             programmierung einsteigen.
  87.             Und zum anderen sind Images sehr flexibel: die Höhe und
  88.             Breite ist vorgebbar, die Anzahl der verwendeten Bitplanes
  89.             und, was auch sehr wichtig ist, die verwendeten Farben
  90.             lassen sich sehr einfach ansteuern.
  91.  
  92.             Deshalb habe ich mich für die Images entschieden.
  93.             In einer zukünftigen Version werde ich vielleicht eine
  94.             andere, schnellere Routine verwenden (kennt jemand eine,
  95.             die genau das selbe tut, nur schneller?).
  96.  
  97.         - blitctrl
  98.  
  99.             Wird als Globale Variable UNBEDINGT FÜR DIE BLITTERERGEBNISSE
  100.             aus der Funktion "Graphcollision" verwendet.
  101.  
  102.         - Blittispeicher
  103.  
  104.             Ja, den müßt ihr selber initialisieren. Und zwar sollte er
  105.             so groß sein wie das größte von euch benutzte Objekt ist.
  106.             Ansonsten macht der Amiga einen Abgang ......
  107.  
  108.         - MyBitMap
  109.  
  110.             Muß die Adresse der BitMap sein. NICHT die Adresse der
  111.             BitPlanes!!!
  112.  
  113.         - MyRPort
  114.  
  115.             Muß der Zeiger auf den dazugehörigen Rastport sein.
  116.  
  117.     Außerdem fehlt noch eine wichtige Sache: die Graphics.Lib MUß VOM
  118.     HAUPTPROGRAMM ERÖFFNET SEIN!!! Ansonsten hol's der Guru.....
  119.  
  120.     Schön und gut, das waren erst einmal alle Konstanten, Variablen und
  121.     Strukturen. Und was kommt jetzt? Logo, die Funktionen. Wenn ihr
  122.     detailierte Informationen haben wollt, so schaut in dem entsprechen-
  123.     den Directory nach, sofern dieses vorhanden ist.
  124.  
  125.     b) Die verwendeten Proceduren und Functionen
  126.  
  127.         1) Procedure GraphCollision( x1, y1, xsize, ysize : short);
  128.  
  129.            Diese Funktion testet den rechteckigen Bereich mit den
  130.            Eckpunkten x1, y1, x1+xsize, y1+ysize, ob in diesem ein
  131.            Punkt gesetz ist.
  132.  
  133.            Aufgerufen wird die Prozedur mit
  134.  
  135.                     GraphCollision(x1, y1, xsize, ysize);
  136.  
  137.            Alle Werte müßen vom Typ Short sein. x1 und y1 bezeichnen den
  138.            oben links stehenden Punkt in einem Rechteck. Der unten rechts
  139.            stehende Punkt wird aus der Addition mit den x- bzw. y-Size
  140.            Werten durch das Betriebssystem ermittelt.
  141.  
  142.            Zu beachten ist, daß meine Routinen folgende Globale Werte
  143.            im Hauptprogramm voraussetzt:
  144.  
  145.            - MyBitMap     ---> Ein Zeiger auf die zu bearbeitende BitMap
  146.                                ( siehe auch das TestProgramm ).
  147.            - Graphics.Lib ---> Diese MUß im Hauptprogramm ERFOLGREICH geöffnet
  148.                                worden sein. Sonst gibts den GURU !
  149.  
  150.            - blitctrl     ---> Enthält nach dem Aufruf den Wert 0 (in
  151.                                dem untersuchten Grfikblock gab es keinen
  152.                                gesetzten Punkt) oder 1 (es war mind.
  153.                                ein Punkt gesetzt).
  154.  
  155.  
  156.            Nach Ende der Prozedur braucht man nur in der Variablen
  157.            blitctrl nachzusehen, ob eine Kollision vorgekommen ist!
  158.  
  159.         Recht einfach, oder? Aber es wird noch lustiger:
  160.  
  161.         2) Function CollObjekt(von, bis, x1, y1, x2, y2 : short) : short;
  162.  
  163.            Die Funktion ermittelt, welches Objekt in dem Rechteck
  164.            x1, y1, x2, y2 kollidiert ist.
  165.  
  166.            Hierbei kann ein von / bis Bereich für die Objektuntersuchung
  167.            angegeben werden (0 - 255 ).
  168.            Wird als Von-Wert -1 angegeben, so werden alle Objekte
  169.            untersucht und die erste Objektnummer, die zur Kollision
  170.            führte, zurück gegeben.
  171.  
  172.            Ist der Rückgabewert -1, so gab es eine Kolision mit einem
  173.            nicht definierten Objekt bzw. das Objekt wurde nicht gefunden.
  174.  
  175.            Die Funktion selber untersucht das definierte Array "Objekt"
  176.            nach folgendem Schema (tut mir leid, passte nicht auf einen
  177.            normalen Bildschirm rauf):
  178.  
  179. ----------------------------------------------------------------------------------------------------
  180.  
  181.            Treffervergleich (O = Objekt, T = Trefferbereich)
  182.  
  183.            Ox1 >= Tx1 und Ox1 =< Tx2    == Ja ==>    Oy1 >= Ty1 und Oy1 <= Ty2   == Ja ==>   Treffer
  184.                      !                         ^                !                       ^
  185.                      !                         !                !                       !
  186.                    Nein                        !              Nein                      !
  187.                      !                         !                !                       !
  188.                      V                         !                V                       !
  189.            Ox2 >= Tx1 und Ox2 =< Tx2    == Ja -+     Oy2 >= Ty1 und Oy2 <= Ty2   == Ja -+
  190.                      !                         ^                !                       ^
  191.                      !                         !                !                       !
  192.                    Nein                        !              Nein                      !
  193.                      !                         !                !                       !
  194.                      V                         !                V                       !
  195.            Tx1 >= Ox1 und Tx1 =< Ox2    == Ja -+     Ty1 >= Oy1 und Ty1 <= Oy2   == Ja -+
  196.                      !                         ^                !                       ^
  197.                      !                         !                !                       !
  198.                    Nein                        !              Nein                      !
  199.                      !                         !                !                       !
  200.                      V                         !                V                       !
  201.            Tx2 >= Ox1 und Tx2 =< Ox2    == Ja -+     Ty2 >= Oy1 und Ty2 <= Oy2   == Ja -+
  202.                      !                                          !
  203.                      !                                          !
  204.                    Nein                                       Nein
  205.                      !                                          !
  206.                      V                                          V
  207.                Kein Treffer                               Kein Treffer
  208.  
  209. ----------------------------------------------------------------------------------------------------
  210.            Wer jetzt sagt "Oh Gott, was ist das für eine komplizierte
  211.            Abfrage" dem kann ich nur Recht geben. Aber schaut euch
  212.            bitte auch das Testprogramm an.
  213.  
  214.            Und wenn das nicht hilft, dann macht es wie ich: malt euch
  215.            auf ein Blatt Papier alle Variationsmöglichkeiten, an dem
  216.            es Kollisionen zwischen Objekten geben kann (auch zwischen
  217.            unterschiedlich großen).
  218.  
  219.            Das Stück hat mich einige Jahre altern lassen!!!
  220.            Ganz zu schweigen von der Zeit. Aber ich habe es ausgiebig
  221.            getestet, weil mit dieser Routine eine Kollisionserkennung
  222.            steht und fällt.
  223.  
  224.            UND SIE STEHT!!!
  225.  
  226.            Sicher, man kann noch einiges zur Beschleunigung tun (auch
  227.            wenn sie jetzt schon, wie mir Tests gezeigt haben, sehr
  228.            schnell ist), aber ich hatte einfach keine Zeit mehr dafür.
  229.  
  230.            In einem späteren Release werde ich sicherlich noch einige
  231.            Minuten dafür verwenden, um sie zu optimieren.
  232.  
  233.         3) Procedure DrawObjekt( VonNr, BisNr : short; MyPlanes,
  234.            NotMyPlanes : byte );
  235.  
  236.            Diese Routine zeichnet, unter Verwendung der
  237.            DrawImage-Funktion der Intuition.Lib ein oder mehrere
  238.            definierte(s) Objekt(e).
  239.  
  240.            Die Variablen "MyPlanes" und "NotMyPlanes" haben
  241.            folgende Bedeutung:
  242.  
  243.                 - Mit "Myplanes" lege ich fest, in welcher Bitplane die
  244.                   Picture-Daten gezeichnet werden sollen.
  245.                   Beispiel:
  246.                             - Ich habe ein Picture mit 2 Bitplanes
  247.                               definiert, welches ich auf einem Bild-
  248.                               schirm mit drei Bitplanes in der 1. und
  249.                               3. Bitplane zeichnen möchte.
  250.  
  251.                               Die Variable "Myplanes" enthält nun für
  252.                               jede zu zeichnende Bitplane ein Bit. D.H.
  253.                               für die 1. Plane das Bit 0, für die 2.
  254.                               Plane das Bit Nr. 1 und so weiter.
  255.  
  256.                               In meinem Beispiel muß ich also den Wert
  257.                               5 vorgeben, da die entsprechende gesetzten
  258.                               Bits den Wert 5 ergeben.
  259.  
  260.                   Alles soweit klar? Na, denn weiter.
  261.  
  262.                 - Mit "NotMyplanes" lege ich fest, was mit den
  263.                   Bitplanes passieren soll, in die ich nicht zeichne.
  264.                   Setze ich hierbei ein Bit, so wird das Objekt in der
  265.                   entsprechenden Zeichenfarbe umrandet.
  266.  
  267.            Habt ihrs verstanden? Wenn nicht, dann probiert es einfach
  268.            mal aus oder seht euch das entsprechende Testprogramm an.
  269.  
  270.         4) Procedure UnDrawObjekt( VonNr, BisNr : short );
  271.  
  272.            Diese Routine löscht die mit VonNr bis BisNr gekennzeichnete
  273.            Objekte auf dem Bildschirm.
  274.  
  275.            Ihr seht, es gibt auch einfache Routinen.
  276.  
  277.         5) Function GetChar() : byte;
  278.  
  279.            Diese Funktion greift direkt auf die Hardwareregister zu und
  280.            ermittelt die gedrückte Taste.
  281.            Der zurückgegeben Wert ist aber NICHT der ASCII-Wert sondern
  282.            vielmehr das Zeichen im "rohen" Format.
  283.  
  284.            Hierzu einige Werte:
  285.                           - AMIGA-links   : $33
  286.                           - AMIGA-rechts  : $31
  287.                           - DEL           : $73
  288.                           - Cursor hoch   : 103
  289.                           - Cursor runter : 101
  290.                           - Cursor rechts :  99
  291.                           - Cursor links  :  97
  292.  
  293.         6) Function GetJoy2(): byte;
  294.  
  295.            Diese Funktion fragt über die Hardwareregister den Joystick
  296.            am Port 2 ab und gibt folgende Wert zurück:
  297.  
  298.               --->   0 - Joystick wurde nicht berührt
  299.               --->   1 - Joystick nach rechts
  300.               --->   2 - Joystick nach links
  301.               --->   4 - Joystick nach hinten
  302.               --->   8 - Joystick nach vorne
  303.               --->  16 - Feuertaste gedrückt.
  304.  
  305.            Zu beachten ist, das jeweils nur das entsprechende Bit
  306.            gesetzt wird, so das es sehr leicht ist, auch mehrere
  307.            Aktionen gleichzeitig abzufragen (z.B. Joystick nach
  308.            rechts und hinten und gleichzeitig wurde die Feuertaste
  309.            gedrückt).
  310.  
  311.         7) Function ChipCopy( Source : Address; Size : integer)
  312.            : Address;
  313.  
  314.            Eine ungeheuer nützlich Funktion (jedenfalls für mich).
  315.  
  316.            Sie allokiert ChipMem in der Größe Size und kopiert die
  317.            Daten von der Addresse Source dort hinein.
  318.            Zurückgegeben wird die ChipMeM-Adresse für die weitere
  319.            Verwendung.
  320.  
  321.            Da eine Programmierung über Pascal zu umständlich war, habe
  322.            ich das ganze über Assembler programmiert (siehe Source).
  323.  
  324.     c) So, das wars erstmal. Leider kann ich euch noch kein
  325.        Beispielprogramm an die Hand geben, welches alle Routinen
  326.        beinhaltet.
  327.  
  328.        Aber wenn ihr euch etwas geduldet werdet ihr mit dem Spiel
  329.        "TakeIt" sehen, was sich alles hiermit anstellen läßt.
  330.  
  331.        Nichts desto trotz liegt es an euch, ob ihr nicht auch
  332.        entsprechende Routinen schreiben wollt euch
  333.        (welche noch zu entwickeln wären steht weiter unten).
  334.  
  335.        Oder setzt euch an eure Freundin und probiert mit den hier
  336.        vorgestellten Routinen aus, ob ihr was auf die Beine stellt.
  337.        Die Grundausstattung habt ihr und es gilt weiterhin der alte
  338.        Spruch: "Jeder ist seines Glückes Schmied".
  339.  
  340. 2.  Aufruf, Übergabeparameter
  341.  
  342.     Siehe in der obigen Dokumentation.
  343.  
  344. 3.  Einbindung in eigene Programme
  345.  
  346.     Hierzu sind folgende Dinge erforderlich:
  347.  
  348.         a) Im Sourcecode ist die Datei "GAME.I" als Include -File
  349.            einzubauen, damit der Compiler auch weiß, was er machen
  350.            soll.
  351.  
  352.         b) Der Linkeraufruf ist wie folgt zu modifizieren:
  353.  
  354.                blink <source>.o+GAME.o to <source> library PCQ.lib
  355.  
  356. 4.  Erklärung des Source-Codes
  357.  
  358.     Ich glaube, eine Erklärung erübrigt sich, da ich die einzelnen
  359.     Schritte dokumentiert habe ( so sollten mal alle Source-Codes
  360.     aussehen).
  361.  
  362. 5.  Sonstiges
  363.  
  364.     Also fangen wir mal wieder an:
  365.  
  366.         a) Die Funktionen sind ALLE von mir ausreichend getestet
  367.            worden. Sie laufen einwandfrei unter der Voraussetzung,
  368.            das man für den Rastport eine WindowRastport wählt.
  369.  
  370.            Warum das so ist weiß ich nicht. Ich weiß nur, das alle
  371.            Versuche, mit einem ScreenRastport zu arbeiten (wg. der
  372.            Ersparnis des gesamten Windowhandlings), mit einer Reise
  373.            zum Guru aufgehört haben.
  374.  
  375.            Vielleicht kann mir ja einer von euch sagen, warum dieses
  376.            so ist. Ich habs nicht verstanden.
  377.  
  378.         b) Die Zeit, die ich in diese Routinen investiert habe, sehe
  379.            ich als sehr groß an (bewegt sich so ca. zwischen 40 - 80
  380.            Stunden inkl. aller Test und Abstürze).
  381.            Deshalb solltet ihr nach Möglichkeit nicht auch nochmal
  382.            versuchen, daß Rad ein zweites Mal zu erfinden! Ich kann
  383.            euch nur warnen. Wer nicht gewarnt sein will, den belegt
  384.            der Gurumaster mit einer langen Zeit schlafloser Nächte,
  385.            vielen Zigaretten (sofern ihr Raucher seid) und jeder
  386.            Menge Kaffee (am anderen Morgen).
  387.  
  388.            Die Testzeit habe ich als sehr kritisch angesehen, da ich
  389.            der Meinung bin, das nur wirklich ausgetestete Programme
  390.            an andere weitergegeben werden sollten.
  391.  
  392.         c) Verbesserungen
  393.  
  394.            O.K., O.K., nicht alle Routinen sind das gelbe vom Ei. Vieles
  395.            könnte sicher noch weiter optimiert werden. Wenn ich die
  396.            entsprechende Zeit habe werde ich mich auch daran setzen.
  397.            Oder wollt ihr dieses vornehmen? Wenn ja, dann schickt mir
  398.            doch bitte eine Diskette mit den Änderungen die ihr
  399.            vorgenommen habt.
  400.  
  401.            Nur um eins möchte ich euch bitten: bleibt bei der
  402.            ObjektDef! Nicht, das ich hierüber das Ja und Amen ausspreche,
  403.            aber solange mir keiner sagen kann, warum die Struktur
  404.            unbedingt erweitert werden müßte, solltet ihr diese auch
  405.            bei euren Programmen nicht weiter verändern.
  406.  
  407.            Falls doch, so laßt uns erstmal darüber diskutiern. Auch ich
  408.            kann noch was lernen.
  409.  
  410.            Und denkt bitte dran: eine ausreichende Dokumentation sollte
  411.            schon sein, sonst ist keinem damit geholfen, weder dem Ein-
  412.            steiger, der verzweifelt ist, weil er den Source nicht lesen
  413.            kann, noch der Programmierer, weil er nach 3 Monaten nicht
  414.            mehr weiß, wie sein Programm funktionierte.
  415.  
  416.         d) Neuentwicklungen
  417.  
  418.            Ich glaube, hier gibt es noch einiges zu machen als da wären:
  419.  
  420.             1) Eine Soundfunktion
  421.  
  422.                Wäre ich besser auf dem Amiga in Punkto Sound, so
  423.                hätte ich auch eine entsprechende Funktion gewählt.
  424.                Bin ich aber nicht!
  425.  
  426.                Ich könnte mir aber vorstellen, daß es eine Routine
  427.                geben könnte, die im Interrupt läuft und auf Anforderung
  428.                Töne von sich geben könnte, wie z.B. Sinusschwingungen,
  429.                Explosionen, Schußgeräusche und noch vieles mehr.
  430.  
  431.                Na, Blut geleckt? Dann ran und schreibt die Routine. Bin
  432.                gespannt, was dabei rauskommt.
  433.  
  434.             2) DualPlayfields
  435.  
  436.                Um auch einen unabhängigen Hintergrund darstellen zu
  437.                können wäre eine Routine erforderlich, welche im
  438.                DualPlayFiled-Modus IFF-Bilddaten lädt und diese in
  439.                einem entsprechende Screen speichert. Wie's dann
  440.                weitergeht, weiß ich nicht.
  441.  
  442.             3) Eine Joystickabfrage für den Port2 bzw. eine
  443.                Mausabfrage.
  444.  
  445.             und so weiter, und so weiter.
  446.  
  447.             Ihr seht, es sind keine Grenzen gesetzt.
  448.  
  449.  
  450. 6.  Copyrights
  451.  
  452.     Die Copyrights für diese Routinen liegen bei mir.
  453.     ( (c) 1992 Jörg Wach )
  454.  
  455.     Ich erlaube allerdings, daß diese Routinen in anderen Programme
  456.     eingesetzt werden dürfen, sofern diese nicht für gewerbsmäßige
  457.     Zwecke verwendet werden.
  458.  
  459.     Gewerbsmäßig bedeutet, daß die Routinen in einem anderen
  460.     Softwareprodukt genutzt oder benutzt werden und dieses
  461.     Softwareprodukt gegen einen Geldwert an Dritte verkauft
  462.     oder verliehen wird.
  463.  
  464.     In diesem Fall bestehe ich auf die Übersendung einer Kopie
  465.     des Programmes sowie auf den Abschluß eines Nutzungsvertrages.
  466.  
  467.     Die Nichtbeachtung kann zu einer strafrechtlichen Verfolgung
  468.     führen.
  469.  
  470.  
  471.     Ich persönlich möchte hiermit keinen abschrecken, der meine Routinen
  472.     verwendet und möchte auch nur sehen, was mit meinen Routinen so
  473.     passiert, aber bei einer gewerbsmäßigen Verwendung in einem
  474.     Produkt betrachte ich es schon als unfair, wenn ich für die
  475.     erbrachte Arbeit nicht entlohnt werde, zumal es sich hierbei um
  476.     harte Basisarbeit gehandelt hat.
  477.  
  478.     Sollte jemand auf die Idee kommen und die Routinen zu
  479.     modifizieren oder zu optimieren so bitte ich doch um die
  480.     Übersendung der neuen Routinen. Auch ich kann noch was lernen!
  481.  
  482.  
  483. 7.  Dateiverzeichnis
  484.  
  485.     Folgende Dateien sollte das Gesamtpacket umfassen:
  486.  
  487.         GAME.MOD    ---> Der Sourcecode
  488.         GAME.I      ---> das Includefile
  489.         GAME.DOC    ---> na was wohl ?
  490.         GAME.MOD.o  ---> Das entsprechende Objektfile zum einbinden
  491.         sowie die entsprechenden Info.-Files und div. Testdateien und
  492.         Dokumentationen.
  493.  
  494.  
  495. So, nun schreibt mal schön eure Programme mit den Routinen und vergesst
  496. bitte nicht, mir eine Kopie zu schicken (natürlich auf Diskette). Ihr
  497. erhaltet die Diskette mit PD-Soft oder der neuesten SoftWare aus meinen
  498. Fingern zurück.
  499.  
  500. PCQ, Take it or Break it
  501.  
  502.         JCL Power
  503.  
  504.             Jörg Wach
  505.             Waitzstr. 75
  506.  
  507.             W-2300 Kiel 1
  508.             Deutschland
  509.  
  510.             30.06.1992
  511.